﻿using System.Text;

namespace App.Tool
{
    /// <summary>
    /// 进制转换
    /// </summary>
    public static class ConvertSystem
    {

        /// <summary>
        /// 转换为base64字符串
        /// </summary>
        /// <param name="instr"></param>
        /// <returns></returns>
        public static string ToBase64(string instr)
        {
            if (string.IsNullOrWhiteSpace(instr))
            {
                return "";
            }

            UTF8Encoding utf8 = new UTF8Encoding();
            Byte[] encodedBytes = utf8.GetBytes(instr);
            return Convert.ToBase64String(encodedBytes);
        }

        /// <summary>
        /// base64字符串—>原字符串
        /// </summary>
        /// <param name="instr"></param>
        /// <returns></returns>
        public static string FromBase64(string instr)
        {
            if (string.IsNullOrWhiteSpace(instr))
            {
                return "";
            }

            return Encoding.UTF8.GetString(Convert.FromBase64String(instr));
        }

        /// <summary>
        /// 字符串转16进制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ToHexString(string s)
        {
            return ToHexString(HexStringToByteArray(s));
        }

        /// <summary>
        /// 16进制转字符串
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string FromHexString(string s)
        {
            var hexBytes = HexStringToByteArray2(s);
            return Encoding.UTF8.GetString(hexBytes);
        }

        /// <summary>
        /// 字符串转16进制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexStringToByteArray(string s)
        {
            try
            {
                if (s.Length == 0)
                    throw new Exception("将16进制字符串转换成字节数组时出错，错误信息：被转换的字符串长度为0。");
                s = s.Replace(" ", "");
                byte[] buffer = new byte[s.Length / 2];
                for (int i = 0; i < s.Length; i += 2)
                    buffer[i / 2] = Convert.ToByte(s.Substring(i, 2), 16);
                return buffer;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 将16进制BYTE数组转换成16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
        {
            try
            {
                string hexString = string.Empty;
                if (bytes != null)
                {
                    StringBuilder strB = new StringBuilder();

                    for (int i = 0; i < bytes.Length; i++)
                    {
                        strB.Append(bytes[i].ToString("X2"));
                        //中间加了一个分割符号
                        if (i < bytes.Length - 1)
                        {
                            strB.Append(" ");
                        }
                        //
                    }
                    hexString = strB.ToString();
                }
                return hexString;
            }
            catch (Exception)
            {
                return "";
            }
        }

        /// <summary>
        /// 16进制字符串转byte数组
        /// </summary>
        /// <param name="hexString">16进制字符</param>
        /// <returns></returns>

        public static byte[] HexStringToByteArray2(string hexString)
        {
            //将16进制秘钥转成字节数组
            var byteArray = new byte[hexString.Length / 2];
            for (var x = 0; x < byteArray.Length; x++)
            {
                var i = Convert.ToInt32(hexString.Substring(x * 2, 2), 16);
                byteArray[x] = (byte)i;
            }
            return byteArray;
        }

        /// <summary>
        /// 进制转换
        /// </summary>
        /// <param name="input"></param>
        /// <param name="fromType">原来的进制格式</param>
        /// <param name="toType">要转换成的进制格式</param>
        /// <returns></returns>
        public static string ConvertGenericBinary(string input, byte fromType, byte toType)
        {
            string output = input;
            switch (fromType)
            {
                case 2:
                    output = ConvertBinaryFromBinary(input, toType);
                    break;
                case 8:
                    output = ConvertGenericBinaryFromOctal(input, toType);
                    break;
                case 10:
                    output = ConvertBinaryFromDecimal(input, toType);
                    break;
                case 16:
                    output = ConvertHex(input, toType);
                    break;
                default:
                    break;
            }
            return output;
        }


        /// <summary>
        /// 二进制转换成其他进制
        /// </summary>
        /// <param name="input"></param>
        /// <param name="toType"></param>
        /// <returns></returns>
        public static string ConvertBinaryFromBinary(string input, byte toType)
        {
            string output = string.Empty;
            var val = Convert.ToInt32(input, 2);

            switch (toType)
            {
                case 8:
                    output = Convert.ToString(val, 8);
                    break;
                case 10:
                    output = Convert.ToString(val, 10);
                    break;
                case 16:
                    output = Convert.ToString(val, 16);
                    break;
                default:
                    output = input.ToString();
                    break;
            }
            return output;
        }

        /// <summary>
        /// 从八进制转换成其他进制
        /// </summary>
        /// <param name="input"></param>
        /// <param name="toType"></param>
        /// <returns></returns>
        private static string ConvertGenericBinaryFromOctal(string input, byte toType)
        {
            string output = string.Empty;
            var val = Convert.ToInt32(input, 8);
            switch (toType)
            {
                case 2:
                    output = Convert.ToString(val, 2);
                    break;
                case 10:
                    output = val.ToString();
                    break;
                case 16:
                    output = Convert.ToString(val, 16);
                    break;
                default:
                    output = input.ToString();
                    break;
            }
            return output;
        }

        /// <summary>
        /// 从十进制转换成其他进制
        /// </summary>
        /// <returns></returns>
        public static string ConvertBinaryFromDecimal(string input, int toType)
        {
            string output = string.Empty;
            var val = Convert.ToInt32(input);

            return ConvertBinaryFromDecimal(val, toType);
        }

        /// <summary>
        /// 从十进制转换成其他进制
        /// </summary>
        /// <returns></returns>
        public static string ConvertBinaryFromDecimal(int input, int toType)
        {
            string output = string.Empty;
            switch (toType)
            {
                case 2:
                    output = Convert.ToString(input, 2);
                    break;
                case 8:
                    output = Convert.ToString(input, 8);
                    break;
                case 16:
                    output = Convert.ToString(input, 16);
                    break;
                default:
                    output = input.ToString();
                    break;
            }
            return output.ToUpper();
        }

        /// <summary>
        /// 16进制转换成其他进制
        /// </summary>
        /// <param name="input"></param>
        /// <param name="toType"></param>
        /// <returns></returns>
        public static string ConvertHex(string input, byte toType)
        {
            string output = string.Empty;
            try
            {
                var val = Convert.ToInt32(input, 16);

                switch (toType)
                {
                    case 8:
                        output = Convert.ToString(val, 8);
                        break;
                    case 10:
                        output = Convert.ToString(val, 10);
                        break;
                    case 2:
                        output = Convert.ToString(val, 2);
                        break;
                    default:
                        output = input.ToString();
                        break;
                }
            }
            catch (Exception)
            {
                output = "0";
            }
            return output;
        }

        /// <summary>
        /// 截取右边多少位数字
        /// </summary>
        /// <param name="input"></param>
        /// <param name="rightNum"></param>
        /// <returns></returns>
        public static string subRight(string input, int rightNum)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                return string.Empty;
            }
            return input.Substring(input.Length - rightNum);
        }
    }
}

